package org.embedchat.server;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandler;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.util.SessionLog;

import org.embedchat.protocol.codec.ChatProtocolCodecFactory;
import org.embedchat.protocol.message.client.LoginMessage;
import org.embedchat.protocol.message.client.RoomsListRequestMessage;
import org.embedchat.protocol.message.common.TextMessage;
import org.embedchat.server.service.ChatEngine;

public class ServerSessionHandler implements IoHandler {
	
	private static Log log = LogFactory.getLog(ServerSessionHandler.class);
	private final boolean useCustomCodec;
	private ChatEngine chatEngine = new ChatEngine(); 

	public ServerSessionHandler(boolean useCustomCodec) {
		this.useCustomCodec = useCustomCodec;
	}

	public void sessionCreated(IoSession session) throws Exception {
		ProtocolCodecFactory codec;
		if (useCustomCodec) {
			codec = new ChatProtocolCodecFactory(true);
		} else {
			codec = new ObjectSerializationCodecFactory();
		}
		session.getFilterChain().addFirst("protocolFilter", new ProtocolCodecFilter(codec));
		session.getFilterChain().addLast("logger", new LoggingFilter());
	}

	public void sessionOpened(IoSession session) {
		log.trace("sessionOpened(" + session.hashCode() + ")");
		session.setIdleTime(IdleStatus.BOTH_IDLE, 600);
		session.setAttachment(new Integer(0));
	}

	public void sessionClosed(IoSession session) {
		chatEngine.processExit(session);		
		log.trace("sessionClosed(" + session.hashCode() + ")");
	}

	public void messageReceived(IoSession session, Object message) {
		log.debug("Message received: " + message);
		if (message instanceof RoomsListRequestMessage) {
			chatEngine.processRoomsListMessage(session, (RoomsListRequestMessage) message);
		}
		if (message instanceof LoginMessage) {
			chatEngine.processLogin(session, (LoginMessage) message);			
		}
		if (message instanceof TextMessage) {
			chatEngine.processTextMessage(session, (TextMessage) message);			
		}
	}

	public void messageSent(IoSession session, Object message) {
	}

	public void sessionIdle(IoSession session, IdleStatus status) {
		SessionLog.info(session, "Disconnecting the idle.");
		session.close();
	}

	public void exceptionCaught(IoSession session, Throwable cause) {
		session.close();
	}
}
